﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace POS
{
    class FileSendRecieveClass
    {
        public class SendFiles
        {
            private static string shortFileName = "";
            private static string fileName = "";

            public static void SelectFile()
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.Title = "File Sharing Client";
                dlg.ShowDialog();
                fileName = dlg.FileName;
                shortFileName = dlg.SafeFileName;

                MessageBox.Show(fileName + "\n\n" + shortFileName);

                SendFile(fileName, shortFileName);
            }

            public static void SendFile(string FILEPATH,string FILENAME)
            {
                string ipAddress = "192.168.1.13";
                int port = 2307;

                Task.Factory.StartNew(() => SendFile(ipAddress, port, FILEPATH, FILENAME));
                MessageBox.Show("File Sent");
            }

            private static void SendFile(string remoteHostIP, int remoteHostPort, string longFileName, string shortFileName)
            {
                try
                {
                    if (!string.IsNullOrEmpty(remoteHostIP))
                    {
                        byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName);
                        byte[] fileData = File.ReadAllBytes(longFileName);
                        byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
                        byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

                        fileNameLen.CopyTo(clientData, 0);
                        fileNameByte.CopyTo(clientData, 4);
                        fileData.CopyTo(clientData, 4 + fileNameByte.Length);

                        TcpClient clientSocket = new TcpClient(remoteHostIP, remoteHostPort);
                        NetworkStream networkStream = clientSocket.GetStream();
                        networkStream.Write(clientData, 0, clientData.GetLength(0));
                        networkStream.Close();

                    }
                }
                catch (Exception E)
                {
                    MessageBox.Show(E.Message);
                }
            }
        }

        public class RecieveFiles
        {
            public delegate void FileRecievedEventHandler(object source, string filename);
            public event FileRecievedEventHandler NewFileRecieved;

            public void StartListeningForFiles()
            {
                this.NewFileRecieved += new FileRecievedEventHandler(Form1_NewFileRecieved);

                int port = int.Parse("2307");
                Task.Factory.StartNew(() => HandleIncomingFile(port));
                //MessageBox.Show("Listening on port:  " + port);
            }

            private void Form1_NewFileRecieved(object sender, string filename)
            {
                //this.BeginInvoke(new Action(delegate()
                //{
                    //MessageBox.Show("New File Recieved\n" + filename);
                    //System.Diagnostics.Process.Start("explorer", Environment.CurrentDirectory);
                //}
                //));
            }

            public void HandleIncomingFile(int port)
            {
                try
                {
                    TcpListener tcplistener = new TcpListener(port);
                    tcplistener.Start();
                    while (true)
                    {
                        Socket handlerSocket = tcplistener.AcceptSocket();
                        if (handlerSocket.Connected)
                        {
                            string filename = string.Empty;
                            NetworkStream networkstream = new NetworkStream(handlerSocket);

                            int thisRead = 0;
                            int blockSize = 1024;
                            Byte[] databyte = new Byte[blockSize];
                            lock (this)
                            {
                                string folderpath = Environment.CurrentDirectory;
                                handlerSocket.Receive(databyte);
                                int filenamelen = BitConverter.ToInt32(databyte, 0);

                                filename = Encoding.ASCII.GetString(databyte, 4, filenamelen);

                                Stream fileStream = File.OpenWrite(folderpath + @"\" +  filename);
                                fileStream.Write(databyte, 4 + filenamelen, (1024 - (4 + filenamelen)));

                                while (true)
                                {
                                    thisRead = networkstream.Read(databyte, 0, blockSize);
                                    fileStream.Write(databyte, 0, thisRead);

                                    if (thisRead == 0)
                                        break;
                                }

                                fileStream.Close();

                            }
                            if (NewFileRecieved != null)
                            {
                                NewFileRecieved(this, filename);
                            }
                            handlerSocket = null;
                        }
                    }
                }
                catch (Exception E)
                {

                }
            }
        }
    }
}
